CON

  _clkmode = xtal1 + pll16x                             ' use crystal x 16
  _xinfreq = 5_000_000

  PC_RX         = 30
  PC_TX         = 31
  clk           = 1
  cs            = 2
  do            = 3
  RTC_wr_btn    = 16
  RTC_wr_led    = 17
  data_wr_btn   = 18
  data_wr_led   = 19
  data_rd_btn   = 20
  data_rd_led   = 21
  rd_sec        = %1000_0001
  rd_min        = %1000_0011
  rd_hr         = %1000_0101

  start_time_hr = 11        'start collection at 1100 Zulu
    
   CHAR5    =  %000_000_000_0_0_000101_00000 
   CHAR4    =  %000_000_000_0_0_000100_00000
   CHAR3    =  %000_000_000_0_0_000011_00000
   CHAR2    =  %000_000_000_0_0_000010_00000
   DEC      =  %000_000_000_0_0_000000_01010
   DEC2     =  DEC+CHAR2
   DEC3     =  DEC+CHAR3  
   DEC4     =  DEC+CHAR4
   DEC5     =  DEC+CHAR5 
VAR

  byte  x
  long ms
  long stack[200]    'was 200
  long adcstack[50]   'was 50
  long runclock[50]      'was 50
  'long cmdstack[10]
  long time
 ' word adcvalue[3840]
 ' byte store_hr[3840]
 ' byte store_min[3840]
 ' byte store_sec[3840] 
  byte month
  byte day
  byte year
  byte hour
  byte minute
  byte second
  byte days_in_month
  byte cmd
  byte cog
  byte cog_adc
  byte cog_display
 ' byte cog_dis
  byte temp_hour
  byte temp_minute
  byte temp_second
  long mem_place
  word  adc
  byte hold_time
    

OBJ

  lcd:   "Serial_Lcd"
  debug: "HyperTerminal"
  num: "Numbers.spin"
  StampDaq: "HyperTerminal"
  RTC: "DS1302"
  
 

PUB Init
  
  ms := clkfreq/1000
  num.init
  'StampDaq.start(PC_TX, PC_RX, 0, 9600)     'turn on to run StampDaq
  'debug.start(PC_TX, PC_RX, 0, 9600)       'turn on to run terminal
  'waitcnt(2000*ms + cnt)     
  'debug.clear(debug#SCREEN)
  dira[RTC_wr_btn]~                          'sets RTC_wr_btn as input
  dira[RTC_wr_led]~~                         'sets RTC_wr_led as output
  dira[data_wr_btn]~
  dira[data_wr_led]~~
  dira[data_rd_btn]~
  dira[data_rd_led]~~
  outa[RTC_wr_led]~
  outa[data_wr_led]~
  outa[data_rd_led]~
 {{ dira[3..1]:= %011                        'set clk and cs as output, do as input
  outa[cs]~~                               'begin with cs high
  outa[clk]~                               'begin clock low }}
  'cognew(display, @stack)                    'starts LCD
 ' cog_adc:=cognew(adc_get, @adcstack)                 'starts ADC
  'cog:=cognew(run_clock, @runclock)               'starts RTC
  Start_cogs
  
  main
  

PUB main 
       StampDaq.start(PC_TX, PC_RX, 0, 2400)

       repeat
         
          if ina[RTC_wr_btn] == 1
            outa[RTC_wr_led]~~
            StampDaq.stop
            cogstop(cog)
            set_clock
            cog:=cognew(run_clock,@runclock)
            outa[RTC_wr_led]~
            StampDaq.start(PC_TX, PC_RX, 0, 2400)
          if ina[data_wr_btn] == 1           'store data
            outa[data_wr_led]~~
            waitcnt(500*ms+cnt)
            store_data
            outa[data_wr_led]~
          if ina[data_rd_btn] == 1           'dump data
            outa[data_rd_led]~~
            waitcnt(500*ms+cnt)
            read_data
            outa[data_rd_led]~ 
          
         case second
           0, 15, 30, 45:
              waitcnt(100*ms+cnt)
              Stop_cogs
              real_time(hour,minute,second,adc)
              Start_cogs
              waitcnt(1000*ms+cnt)
                 
PUB Start_cogs
    cog_display:=cognew(display, @stack)
    cog:=cognew(run_clock, @runclock)               'starts RTC 
    cog_adc:=cognew(adc_get, @adcstack)

Pub Stop_cogs
    cogstop(cog_display)
    cogstop(cog_adc)
    cogstop(cog) 

PUB read_data
  Stop_cogs
  repeat mem_place from 0 to 4079        '17 hours of data
    waitcnt(10*ms+cnt)
    real_time(store_hr[mem_place],store_min[mem_place],store_sec[mem_place],adcvalue[mem_place])      
    if ina[data_rd_btn] == 1
      outa[data_rd_led]~
      waitcnt(1000*ms+cnt)
      Start_cogs
      return   
      
  
PUB store_data
   'StampDaq.start(PC_TX, PC_RX, 0, 2400)    'this area for sending live to Excel
   repeat while (hour <> start_time_hr)
    case second
           0, 15, 30, 45:
              waitcnt(100*ms+cnt)
              Stop_cogs
              real_time(hour,minute,second,adc)
              Start_cogs
              waitcnt(1000*ms+cnt)
  
   mem_place~              
   repeat while (mem_place < 4079) and ina[data_wr_btn] <> 1     '17 hours of data
   '
      'waitcnt(1000*ms+cnt)
      case second
        0, 15, 30, 45:
          waitcnt(100*ms+cnt)
          Stop_cogs
          store_hr[mem_place]:=hour
          store_min[mem_place]:=minute
          store_sec[mem_place]:=second
          adcvalue[mem_place]:=adc
          real_time(store_hr[mem_place],store_min[mem_place],store_sec[mem_place],adcvalue[mem_place]) 
          mem_place++
          Start_cogs
          outa[data_wr_led]~
          waitcnt(1000*ms+cnt)
          outa[data_wr_led]~~
          
                    
   repeat
      !outa[data_wr_led]
      waitcnt(100*ms+cnt)
      if ina[data_rd_btn] == 1
        waitcnt(500*ms+cnt)
        outa[data_wr_led]~
        return
        
PUB real_time(hour1,minute1,second1,adc1)
      
     ' cogstop(cog_adc)
      'cogstop(cog)
      
      StampDaq.str(@UUUU)            'needed to sycronize the RF datalink if used
      waitcnt(20*ms+cnt)
      StampDaq.tx(13)
      waitcnt(10*ms+cnt)
      StampDAQ.str(@DATA)
      waitcnt(20*ms+cnt)
      StampDaq.str(num.ToStr(hour1,DEC4))
      waitcnt(10*ms+cnt)
      StampDaq.tx(",")
      waitcnt(10*ms+cnt)
      StampDaq.str(num.ToStr(minute1,DEC4))
      waitcnt(10*ms+cnt)
      StampDaq.tx(",")
      waitcnt(10*ms+cnt)
      StampDaq.str(num.ToStr(second1,DEC4))
      waitcnt(10*ms+cnt)
      StampDaq.tx(",")
      waitcnt(10*ms+cnt)
      StampDaq.str(num.ToStr(adc1,DEC5))
      waitcnt(20*ms+cnt)
      StampDaq.tx(13)

      'cog:=cognew(run_clock, @runclock)               'starts RTC 
      'cog_adc:=cognew(adc_get, @adcstack)


     
  
PUB run_clock
    repeat 
      second:=RTC.read(rd_sec)
      minute:=RTC.read(rd_min)
      hour:=RTC.read(rd_hr)
      

PUB display | adcOld,hrtemp

  lcd.start(0,19200,2)                  
  lcd.cursor(0)
  lcd.cls
  
  repeat
    
    'if adc <> adcOld
      lcd.gotoxy(0,0)
      lcd.str(string("TIME:"))
      'lcd.str(num.ToStr(hour*100+minute,DEC5))
      hrtemp:=hour                       'used to force display of "00" hour
      if hrtemp< 10
        hrtemp:=hrtemp+100
      'lcd.str(num.ToStr(second,DEC5))
      lcd.str(num.ToStr(hrtemp*10000+minute*100+second,%000_001_101_0_1_001001_01010))
       
      lcd.clrln(1)
      lcd.gotoxy(0,1)
      lcd.str(string("ADC:"))
      lcd.str(num.ToStr(adc,DEC5))
      'lcd.str(num.ToStr(adc,%000_000_000_0_0_000000_01010))
    '  lcd.putc(adc)
      waitcnt(500*ms + cnt)
      'adcOld := adc   

pub adc_get  | adctemp,adcave              'for use with the MCP3001 10-bit ADC
  dira[3..1]:= %011                        'set clk and cs as output, do as input
  outa[cs]~~                               'begin with cs high
  outa[clk]~                               'begin clock low
'start adc
   repeat
     adcave~
     repeat 100
        adctemp~
        outa[cs]~                                'clear cs to start adc
        repeat 3
         outa[clk]~~                            'three clock pulses required to start adc
          outa[clk]~                             'two pulses to charge internal cap
                                             'one pulse to clear the first bit which is nul
                                                 'end start pulse

        repeat 10                                'get 10 bits MSB first
          adctemp<<=1                            'shift left 1 place
          outa[clk]~~                            'bit set for high of clock pulse
          adctemp:= adctemp | ina[do]            'data bit OR'ed with previous bits (shifted left)
          outa[clk]~                             'complete clock pulse
        waitcnt(5*ms + cnt)  
        outa[cs]~~                               'set cs high to stop conversion
        repeat 2                                 '2 stop pulses to clear adc
          outa[clk]~~
          outa[clk]~
                                 
        adcave:=adcave+adctemp                             'put result in global variable           
        'waitcnt(5*ms + cnt)

     adc:=adcave/100
    
     
pub set_clock | count,temp

  debug.start(PC_TX, PC_RX, 0, 9600)       'turn on to run terminal
  waitcnt(2000*ms + cnt)     
  debug.clear(debug#SCREEN)
  month:=13                     'force a month out of bounds
  repeat until month < 13 and month >0
    debug.clear(debug#SCREEN)
    waitcnt(500*ms +cnt)
    debug.Str(@monthprompt)     'send month entry prompt
    temp:=debug.rx             'get first digit
    debug.tx(temp)              'echo it back
    temp:=debug.StrToDec(@temp)*10  'convert ascii to dec
    count:=debug.rx               'get second digit
    debug.tx(count)               'echo it back
    month:=temp+debug.StrToDec(@count) 'combine digits
  debug.str(num.ToStr(month,DEC3))  'echo it back
  debug.Cr                         'return and line feed

  days_in_month:=32                'default max days in month
  case month
    4,6,9,11:days_in_month:=31
    2:days_in_month:=30
  day:=32                                'force a day out of bounds to start
  
  repeat until day < days_in_month and day > 0
    debug.ClearLine             
    debug.clear (debug#LINE)
    waitcnt(500*ms + cnt)
    debug.Str(@dayprompt)
    temp:=debug.rx
    debug.tx(temp)
    temp:=debug.StrToDec(@temp)*10
    count:=debug.rx
    debug.tx(count)
    day:=temp+debug.StrToDec(@count)
  debug.str(num.ToStr(day,Dec3))
  debug.Cr

  debug.Str(@yearprompt)
  year:=debug.rx
  debug.tx(year)
  year:=debug.StrToDec(@year)*10
  count:=debug.rx
  debug.tx(count)
  year:=year+debug.StrToDec(@count)
  debug.str(num.ToStr(year,Dec3))
  debug.Cr 
  

  hour:=24
  repeat until hour <24
    debug.ClearLine
    debug.clear (debug#LINE)
    waitcnt(500*ms + cnt)
    debug.Str(@hourprompt)
    temp:=debug.rx
    debug.tx(temp)
    temp:=debug.StrToDec(@temp)*10
    count:=debug.rx
    debug.tx(count)
    hour:=temp+debug.StrToDec(@count)
  debug.str(num.ToStr(hour,Dec3))
  debug.Cr

  minute:= 60
  repeat until minute < 60
    debug.ClearLine                'returns to beginning of the line for clear
    debug.clear (debug#LINE)
    waitcnt(500*ms + cnt)
    debug.Str(@minuteprompt)
    temp:=debug.rx
    debug.tx(temp)
    temp:=debug.StrToDec(@temp)*10
    count:=debug.rx
    debug.tx(count)
    minute:=temp+debug.StrToDec(@count)
  debug.str(num.ToStr(minute,Dec3))
  debug.Cr
  
  second:= 60
  repeat until second < 60
    debug.ClearLine
    debug.clear (debug#LINE)
    waitcnt(500*ms + cnt)
    debug.Str(@secondprompt)
    temp:=debug.rx
    debug.tx(temp)
    temp:=debug.StrToDec(@temp)*10
    count:=debug.rx
    debug.tx(count)
    second:=temp+debug.StrToDec(@count)
  debug.str(num.ToStr(second,Dec3))
  waitcnt(5*ms+cnt)
  debug.stop                                          'release COG 
  RTC.set_RTC(year,month,day,hour,minute,second)
  'debug.stop                                          'release COG

  
dat
    UUUU byte "UUUU",0
    DATA byte "DATA,",0
    monthprompt byte "Month (as two digits): ", 0
    dayprompt byte "Day (01 to 28, 29, 30, or 31): ",0
    yearprompt byte "Year (## assuming 20##): ",0
    hourprompt byte "Hour (00 to 23): ",0
    minuteprompt byte "Minute (00 to 59): ",0
    secondprompt byte "Second (00 to 59): ",0
    adcvalue word $00[4080]
    
    store_hr byte $00[4080]
    store_min byte $00[4080]
    store_sec byte $00[4080]
  
      
   